package com.laowang.project.system.controller;

import com.alibaba.fastjson.JSONObject;
import com.laowang.common.exception.CustomException;
import com.laowang.common.utils.StrUtils;
import com.laowang.common.utils.StringUtils;
import com.laowang.common.utils.http.HttpKit;
import com.laowang.framework.redis.RedisCache;
import com.laowang.framework.web.domain.AjaxResult;
import com.laowang.project.pay.config.WeixinOpen;
import com.laowang.project.pay.config.WeixinOpenNew;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;


/**
 * @Auther laowang
 * @Date 2021/6/1
 * @Description   验证微信公众号的token
 */
@Api(tags = "微信token相关")
@Slf4j
@RestController
public class WinxinNewController {




    @Autowired
    private RedisCache redisCache;

    @RequestMapping(value = "/wxconnectnew",produces = "application/json;charset=UTF-8")
    public  void wxconnectnew(@RequestParam(name = "signature", required = false) String signature,
                               @RequestParam(name = "timestamp", required = false) String timestamp,
                               @RequestParam(name = "nonce", required = false) String nonce,
                               @RequestParam(name = "echostr", required = false) String echostr,HttpServletRequest req, HttpServletResponse response) throws Exception {
        /*InputStream is = req.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = null;
        while((line = reader.readLine()) != null) {
            sb.append(line + "\n");
        }

        System.out.println("收到的字符串:"+sb.toString());*/
        Signature sg = new Signature(signature,timestamp,nonce, echostr);
        System.out.println(sg);
        String method = req.getMethod();
        System.out.println("method:"+method);
        //System.out.println("response:"+response);
        // 如果是微信发过来的GET请求
        if("GET".equals(method)){
            if(checkSignature(sg)){
                System.out.println("微信连接成功！");
                response.setContentType("application/json;charset=UTF-8");
                //\并且设置编码
                response.setCharacterEncoding("UTF-8");
                //response.reset();
                //System.out.println("writer:"+response.getWriter());
                response.getWriter().write(sg.getEchostr());
            }
        }else if ("POST".equals(method)){

        }


    }

    //获取access_token
    @ApiOperation(value = "获取公众号分享加密串",notes = "")
    @GetMapping(value = "/getTokenNew")
    public AjaxResult getTokenNew(String url) throws Exception {

        String access_token = redisCache.getCacheObject("access_token");

        if (StringUtils.isEmpty(access_token)){
            String  url1  ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
            url1 =  String.format(url1, WeixinOpenNew.appId,WeixinOpenNew.secret);
            String s = HttpKit.get(url1);
            Map<String,String> map = JSONObject.parseObject(s, Map.class);
            System.out.println(map);
            access_token = map.get("access_token");
            redisCache.setCacheObject("access_token",access_token,7100, TimeUnit.SECONDS);//一个半小时

        }

        String  url2  ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi";
        url2 = String.format(url2,access_token);
        String res = HttpKit.get(url2);
        Map<String,Object> resmap = JSONObject.parseObject(res, Map.class);
        System.out.println(resmap);
        Integer code =(Integer) resmap.get("errcode") ;
        if (!code.equals(0)){
            throw new CustomException("活动签名异常");
        }
        String ticket = (String) resmap.get("ticket");
        TreeMap<String, Object> params = new TreeMap<>();
        params.put("noncestr", StrUtils.getComplexRandomString(9));//随机字符串
        params.put("jsapi_ticket", ticket);
        //SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
        //String now = format.format(new Date());
        Date date = new Date();
        Long now = date.getTime()/ 1000;
        params.put("timestamp", now);
        params.put("url",url);

        StringBuilder sb = new StringBuilder();
        for (String key : params.keySet()) {
            sb.append("&").append(key).append("=").append(params.get(key));
        }
        //String string1 = sb.substring(0, sb.lastIndexOf("&"));
        String string1 = sb.toString().replaceFirst("&", "");
        String signature = getSha1(string1);
        params.put("signature",signature);

        return AjaxResult.success(params);
    }

    //获取access_token
    @GetMapping(value = "/getToken")
    public String getToken1() throws Exception {
        String access_token = redisCache.getCacheObject("access_token");

        if (StringUtils.isEmpty(access_token)){
            String  url  ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
            url =  String.format(url, WeixinOpenNew.appId,WeixinOpenNew.secret);
            String s = HttpKit.get(url);
            Map<String,String> map = JSONObject.parseObject(s, Map.class);
            String accessToken = map.get("access_token");
            redisCache.setCacheObject("access_token",accessToken,5400, TimeUnit.SECONDS);//一个半小时
            return s;
        }else {
            return access_token;
        }

        //access_token:{"access_token":"70_Q4hXa0efJlppLu1e34s-xtOh9KvPjResVn6phbj9uHaN5ozXtOoEy1UpTW2nwwvOofM2mQGoNkwY8cuyGsjoAuJFFA6zMbKhJQguwkUOe8quq7_eoGkoANDWahUQEIfAJADRV","expires_in":7200}

    }

    /**
     *  查询自定义菜单
     * @throws Exception
     */
    @GetMapping(value = "/queryMenu1")
    public void queryMenu1() throws Exception {
        String token = getToken1();
        //自定义菜单
        String url  ="https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=%s";
        //默认菜单和全部个性化菜单
        //String url =    "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=%s";
        //String url =    "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=%s";
        url =  String.format(url,token);
        //System.out.println(url);
        String s = HttpKit.get(url);
        log.error("json数据:{}",s);
        //access_token:{"access_token":"70_Q4hXa0efJlppLu1e34s-xtOh9KvPjResVn6phbj9uHaN5ozXtOoEy1UpTW2nwwvOofM2mQGoNkwY8cuyGsjoAuJFFA6zMbKhJQguwkUOe8quq7_eoGkoANDWahUQEIfAJADRV","expires_in":7200}

    }


    public static void main(String[] args) throws Exception {
        WinxinNewController winxinController = new WinxinNewController();
        winxinController.getToken1();
    }



    public static boolean checkSignature(Signature sg) {

        String[] arr = new String[] { WeixinOpenNew.token, sg.getTimestamp(), sg.getNonce() };
        // 排序
        Arrays.sort(arr);
        // 生成字符串
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < arr.length; i++) {
            content.append(arr[i]);
        }

        // sha1加密
        String temp = getSha1(content.toString());
        // 比较
        return temp.equals(sg.getSignature());
    }


    // 加密算法
    public static String getSha1(String str) {
        if (str == null || str.length() == 0) {
            return null;
        }

        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));
            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j * 2];
            int k = 0;

            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }

            return new String(buf);
        } catch (Exception e) {
            return null;
        }

    }

    @NoArgsConstructor
    @AllArgsConstructor
    @Data
    class Signature{
        private String signature;
        private String timestamp;
        private String nonce;
        private String echostr;
    }
}
